/**
 * Copyright  (c) 2009-2013 XLab,  Org. 
 * All  rights  reserved. 
 */
package org.xlab.baseframework.system;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.MessageSource;
import org.xlab.baseframework.common.comparator.SystemListenerComparator;
import org.xlab.baseframework.exception.SystemRuntimeException;
import org.xlab.baseframework.service.spi.ISystemInitializationListener;


/**
 * 系统启动完成的监听器
 * 
 * @author MaKuBEX Email:makubexnet@gmail.com
 * @version 1.0.0 Sep 7, 2010
 * @since 1.0.0
 * 
 */
public final class SystemStartup implements InitializingBean,
		ApplicationContextAware, Serializable {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = 851741997238789675L;
	private static final Logger log = Logger.getLogger(SystemStartup.class);
	private ApplicationContext applicationContext;
	@Autowired(required = true)
	@Qualifier("bpf_systemMessageSource")
	private MessageSource messageSource;

	/**
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws Exception {
		String message = this.messageSource.getMessage(
				"info.syste.startup.start", null, "System is starting now...",
				Locale.getDefault());
		log.debug(message);
		Map<String, ISystemInitializationListener> allListeners = this.applicationContext
				.getBeansOfType(ISystemInitializationListener.class);
		if (!allListeners.isEmpty()) {
			List<ISystemInitializationListener> sortedList = new ArrayList<ISystemInitializationListener>(
					allListeners.values());
			Collections.sort(sortedList, new SystemListenerComparator());
			message = this.messageSource.getMessage(
					"info.system.startup.listener.list",
					new Object[] { sortedList },
					"System startup listener list\n" + sortedList.toString(),
					Locale.getDefault());
			log.debug(message);
			for (ISystemInitializationListener listener : sortedList) {
				try {
					listener.onSystemStarted();
				} catch (SystemRuntimeException re) {
					message = this.messageSource.getMessage(
							"info.system.startup.listener.failed",
							new Object[] { listener, re },
							"ystem startup failed! Exception occured on listener["
									+ listener + "], cased by\n" + re,
							Locale.getDefault());
					log.error(message);
					throw re;
				}
			}
		}
		message = this.messageSource.getMessage("info.system.startup.finish",
				null, "System has started!", Locale.getDefault());
		log.debug(message);
	}

	/**
	 * @return the messageSource
	 */
	public MessageSource getMessageSource() {
		return messageSource;
	}

	/**
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
	 */
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	/**
	 * @param messageSource the messageSource to set
	 */
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}
}
